#pragma once

#include <string>

#include "noncopyable.h"

#define LOG_INFO(LogmsgFormat, ...) \
  do  { \
    Logger &logger = Logger::instance(); \
    logger.setLogLevel(INFO); \
    char buf[1024]; \
    snprintf(buf, sizeof(buf), LogmsgFormat, ##__VA_ARGS__); \
    logger.log(buf); \
  } while (0);

#define LOG_ERROR(LogmsgFormat, ...) \
  do { \
    Logger &logger = Logger::instance(); \
    logger.setLogLevel(ERROR); \
    char buf[1024]; \
    snprintf(buf, sizeof(buf), LogmsgFormat, ##__VA_ARGS__); \
    logger.log(buf); \
  } while (0);

#define LOG_FATAL(LogmsgFormat, ...) \
  do { \
    Logger &logger = Logger::instance(); \
    logger.setLogLevel(FATAL); \
    char buf[1024]; \
    snprintf(buf, sizeof(buf), LogmsgFormat, ##__VA_ARGS__); \
    logger.log(buf); \
    exit(-1); \
  } while (0);

#ifdef MUDEBUG
#define LOG_DEBUG(LogmsgFormat, ...) \
  do { \
    Logger &logger = Logger::instance(); \
    logger.setLogLevel(DEBUG); \
    char buf[1024]; \
    snprintf(buf, sizeof(buf), LogmsgFormat, ##__VA_ARGS__); \
    logger.log(buf); \
  } while (0)
#else
  #define LOG_DEBUG(LogmsgFormat,...)
#endif

// 定义日志级别 INFO ERROR FATAL DEBUG

enum LogLevel {
  INFO, // 普通信息
  ERROR, // 错误信息
  FATAL, // core信息
  DEBUG, // 调试信息
};

class Logger : noncopyable {
public:
  // 获取日志唯一的实例对象
  static Logger& instance();
  void setLogLevel(const int level);
  void log(const std::string& msg);
private:
  int m_logLevel;
  Logger() {}
};